package com.spzx.payment.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.rabbit.constant.MqConst;
import com.spzx.common.rabbit.service.RabbitService;
import com.spzx.order.api.RemoteOrderInfoService;
import com.spzx.order.api.domain.OrderInfo;
import com.spzx.payment.config.AlipayConfig;
import com.spzx.payment.domain.PaymentInfo;
import com.spzx.payment.service.AlipayService;
import com.spzx.payment.service.PaymentInfoService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Map;

@Slf4j
@Service
public class AlipayServiceImpl implements AlipayService {

    @Autowired
    private AlipayClient alipayClient;

    @Autowired
    private PaymentInfoService paymentInfoService;

    @Autowired
    private RemoteOrderInfoService remoteOrderInfoService;

    @Autowired
    private RabbitService rabbitService;

    /**
     * 支付宝支付提交表单
     *
     * @param orderNo
     * @return
     */

//    @SneakyThrows
    @Override
    public String submitAlipay(String orderNo) throws AlipayApiException {

        // 调用service层保存支付记录
        PaymentInfo paymentInfo = paymentInfoService.savePaymentInfo(orderNo);
        // 创建请求对象
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request
        // 同步回调
        alipayRequest.setReturnUrl(AlipayConfig.return_payment_url);
        // 异步回调
        alipayRequest.setNotifyUrl(AlipayConfig.notify_payment_url);

        /******必传参数******/
        JSONObject bizContent = new JSONObject();
        //商户订单号，商家自定义，保持唯一性
        bizContent.put("out_trade_no", paymentInfo.getOrderNo());
        //支付金额，最小值0.01元
//        bizContent.put("total_amount", "0.01");
        bizContent.put("total_amount", paymentInfo.getAmount());

        //订单标题，不可使用特殊符号
        bizContent.put("subject", paymentInfo.getContent());
        /******可选参数******/
        //手机网站支付默认传值QUICK_WAP_WAY
        bizContent.put("product_code", "QUICK_WAP_WAY");

        //设置业务参数
        alipayRequest.setBizContent(bizContent.toString());
        AlipayTradeWapPayResponse response = alipayClient.pageExecute(alipayRequest, "POST");
/*        System.out.println("---------------------------------------");
        System.out.println(response.getCode());
        System.out.println("---------------------------------------");
        System.out.println(response.getMsg());*/
        String form = response.getBody();
        System.out.println(form);
        //生产form表单
        return form; //调用SDK生成表单;
    }

    /**
     * 支付宝异步回调
     *
     * @param paramMap
     * @param request
     * @return
     */
    @Override
    public String handleAlipayNotify(Map<String, String> paramMap, HttpServletRequest request) {
        String result = "failure";

        try {
            //调用SDK验证签名
            //rsaCheckV1 : RSA2
            boolean signVerified = AlipaySignature.rsaCheckV1(
                    paramMap,//支付宝返回过来的请求参数
                    AlipayConfig.alipay_public_key,//支付宝公钥
                    AlipayConfig.charset,//编码格式
                    AlipayConfig.sign_type//签名类型
            );

            //校验验签是否成功
            String outTradeNo = paramMap.get("out_trade_no");
            if (!signVerified) {
                log.error("订单 {} 验签失败", outTradeNo);
                return result;
            }
            log.info("验签成功！");

            //商家需要验证该通知数据中的 out_trade_no 是否为商家系统中创建的订单号。
            R<OrderInfo> orderInfoResult = remoteOrderInfoService.getByOrderNo(outTradeNo, SecurityConstants.INNER);
            if (R.FAIL == orderInfoResult.getCode()) {
                log.error("远程获取订单 {} 失败", outTradeNo);
                return result;
            }
            if (orderInfoResult.getData() == null) {
                log.error("订单 {} 不存在", outTradeNo);
                return result;
            }
            OrderInfo orderInfo = orderInfoResult.getData();

            // 判断 total_amount 是否确实为该订单的实际金额（即商户订单创建时的金额）。
            BigDecimal totalAmount = new BigDecimal(paramMap.get("total_amount"));
            if (orderInfo.getTotalAmount().compareTo(totalAmount) != 0) {
                log.error("订单 {} 金额不一致", outTradeNo);
                return result;
            }

            // 校验通知中的 seller_id（或者 seller_email) 是否为 out_trade_no
            // 这笔单据的对应的操作方（有的时候，一个商家可能有多个 seller_id/seller_email）。
            // "2088721053938288" 沙箱中的 商户PID
            String sellerId = paramMap.get("seller_id");
            if (!AlipayConfig.seller_id.equals(sellerId)) {
                log.error("订单 {} 商家不一致", outTradeNo);
                return result;
            }

            //验证 app_id 是否为该商家本身。
            String appId = paramMap.get("app_id");
            if (!AlipayConfig.app_id.equals(appId)) {
                log.error("订单 {} appid不一致", outTradeNo);
                return result;
            }

            // 交易状态
            String tradeStatus = paramMap.get("trade_status");
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {

                PaymentInfo paymentInfo = paymentInfoService.getOne(
                        new LambdaQueryWrapper<PaymentInfo>()
                                .eq(PaymentInfo::getOrderNo, outTradeNo)
                                .eq(PaymentInfo::getPayType, 2));// 根据订单号和支付类型查询付款信息
                int paymentStatus = Integer.parseInt(paymentInfo.getPaymentStatus());

                // 幂等性判断：如果支付状态已经是已支付，则直接返回
                if (paymentStatus == 1) {
                    return "success";
                }
                // 正常的支付成功，我们应该更新交易记录状态
                paymentInfoService.updatePaymentStatus(paymentInfo, paramMap, 2);

                //基于MQ通知订单系统，修改订单状态
                rabbitService.sendMessage(MqConst.EXCHANGE_PAYMENT_PAY, MqConst.ROUTING_PAYMENT_PAY, outTradeNo);
                //基于MQ通知商品系统，扣减库存
                rabbitService.sendMessage(MqConst.EXCHANGE_PRODUCT, MqConst.ROUTING_MINUS, outTradeNo);

                return "success";
            }

        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new ServiceException("支付宝支付回调异常");
        }
        return result;
    }
}
